<?php

namespace app\shopapi\model;

use app\admin\model\shop\Config;
use fast\Date;
use think\Log;

class Sound
{

    //protected $access_key_id = "DXKJ_213_DEV";
    //protected $AccessKey     = "hzlMbOAKy5bHMo9zJwbykcRdAy5AX2vMonS6XoTjPd1qDEkJFbqcFdqKTOygyO4Q";
    //protected $device_id     = "H810D2408020101";
    protected $access_key_id;
    protected $AccessKey;
    protected $baseUrl       = "http://its.newpostech.cn:26080/horn/pushmsg";
    protected $baseMultiUrl      = "http://its.newpostech.cn:26080/horn/multi_pushmsg";

    public function __construct()
    {
        $config = Config::field('sound_access_key_id,sound_access_key')->find(1);
        $this->access_key_id = $config['sound_access_key_id'];
        $this->AccessKey = $config['sound_access_key'];
    }

    //消息推送(单台)
    public function singleInvoke($request_data,$device_id)
    {
        $data = [
            'access_key_id'=>$this->access_key_id,
            'request_id'=>$this->getMicrosecond(),
            'device_id'=>$device_id,
            'request_data'=>$request_data,
            'push_template'=>'00',
            'nonce'=>$this->uuid(),
        ];
        $signSortStr = $this->coveString($data);

        $sign  = $this->getSign($signSortStr, $this->AccessKey);

        $data['sign'] = $sign;

        $body = json_encode($data);

        $resp = $this->sendPost($this->baseUrl, $body);

        $respObj = json_decode($resp, true);

        if ($respObj['code']==0000){
            return $respObj;
        } else {
            throw new \Exception($respObj['msg_desc']);
        }


    }

    //消息推送(多台)
    public function multiInvoke($request_data,$shop_id)
    {
        $sound_list = collection(ShopSound::where(['shop_id'=>$shop_id])->limit(5)->field('device_id')->select())->toArray();
        Log::error('音响:');

        if (count($sound_list)==0){
            return false;
        }
        $data = [
            'access_key_id'=>$this->access_key_id,
            'request_id'=>$this->getMicrosecond(),
            'device_list'=>json_encode($sound_list,JSON_UNESCAPED_SLASHES),
            'request_data'=>$request_data,
            //'push_template'=>'01',
            'push_template'=>'00',
            'nonce'=>$this->uuid(),
        ];

        $signSortStr = $this->coveString($data);

        $sign  = $this->getSign($signSortStr, $this->AccessKey);

        $data['sign'] = $sign;
        $data['device_list'] = $sound_list;

        $body = json_encode($data,320);

        $resp = $this->sendPost($this->baseMultiUrl, $body);

        $respObj = json_decode($resp, true);

        if ($respObj['code']==0000){
            return $respObj;
        } else {
            throw new \Exception($respObj['msg_desc']);
        }
    }

    public function cancelMultiInvoke($request_data,$shop_id)
    {
        $sound_list = collection(ShopSound::where(['shop_id'=>$shop_id])->limit(5)->field('device_id')->select())->toArray();
        Log::error('音响:');

        if (count($sound_list)==0){
            return false;
        }
        $data = [
            'access_key_id'=>$this->access_key_id,
            'request_id'=>$this->getMicrosecond(),
            'device_list'=>json_encode($sound_list,JSON_UNESCAPED_SLASHES),
            'request_data'=>$request_data,
            'push_template'=>'00',
            'nonce'=>$this->uuid(),
        ];

        $signSortStr = $this->coveString($data);

        $sign  = $this->getSign($signSortStr, $this->AccessKey);

        $data['sign'] = $sign;
        $data['device_list'] = $sound_list;

        $body = json_encode($data,320);

        $resp = $this->sendPost($this->baseMultiUrl, $body);

        $respObj = json_decode($resp, true);

        if ($respObj['code']==0000){
            return $respObj;
        } else {
            throw new \Exception($respObj['msg_desc']);
        }
    }


    public function getMicrosecond() {
        list($microsecond, $time) = explode(' ', microtime());
        return strval( sprintf('%.0f',(floatval($microsecond)+floatval($time))*1000000));
    }

    public function sendPost($baseUrl, $body) {

        $option = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-Type:application/json',
                'content' => $body,
                'timeout' => 5         // 超时时间，单位秒
            )
        );
        $context = stream_context_create($option);
        $result = file_get_contents($baseUrl, false, $context);

        return $result;
    }

    public function uuid()
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid  =  substr ( $chars,  0,  8 ) . '-'
            . substr ( $chars,  8,  4 ) . '-'
            . substr ( $chars, 12,  4 ) . '-'
            . substr ( $chars, 16,  4 ) . '-'
            . substr ( $chars, 20, 12 );
        return $uuid ;
    }

    /**
     * 生成待签名字符串
     * @param map
     * @return
     */
    public function coveString($arr) {
        $first_ele = true;
        $signSortStr = "";
        $tmparr = $arr;

        ksort($tmparr);

        foreach($tmparr as $x_key=>$x_value) {
            if ($x_key == "sign")
                continue;
            if ($first_ele == true) {
                $signSortStr = $signSortStr . $x_key . "=" . $x_value;
                $first_ele = false;
            } else {
                $signSortStr = $signSortStr . "&" . $x_key . "=" . $x_value;
            }
        }

        return $signSortStr;
    }

    /**
     * 对签名的报文进行加密处理
     * @param str
     * @return 签名字符串
     */
    public function getSign($str, $access_key_sercert) {
        $sign = hash_hmac("sha256", $str, $access_key_sercert);
        return base64_encode(hex2bin($sign));
    }

    /**
     * 验证签名
     * @param sign 签名
     * @param access_key_sercert 密钥
     * @param arr 数据
     * @return 0 相等
     */
    public function verify($sign, $arr, $access_key_sercert){
        $signStr = $this->coveString($arr);
        $sign2 = $this->getSign($signStr, $access_key_sercert);
        return strcmp($sign , $sign2);
    }


}